﻿using System;
using System.Collections.Generic;
using System.Data.SqlClient;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace DAO
{
    public class DAOFactura  
    {
        public static void Guardar(Entidad.EntidadFactura factura)
        {
            AccesoDato ad = new AccesoDato();
            SqlConnection cn = new SqlConnection();
            SqlTransaction tran = null;
            cn.ConnectionString = ad.getCadena();
            try
            {
                cn.Open();
                tran = cn.BeginTransaction();
                SqlCommand cmd = new SqlCommand();
                cmd.CommandType = System.Data.CommandType.Text;
                cmd.CommandText = "INSERT INTO factura (id_tipo_factura,fecha,id_tipo_pago,id_cliente,total) values(@id_tipo_factura,@fecha,@id_tipo_pago,@id_cliente,@total);Select @@Identity";
                cmd.Connection = cn;
                cmd.Parameters.AddWithValue("@id_tipo_factura", factura.id_tipo_factura);
                cmd.Parameters.AddWithValue("@fecha", factura.fecha);
                cmd.Parameters.AddWithValue("@id_tipo_pago", factura.id_tipo_pago);
                cmd.Parameters.AddWithValue("@id_cliente", factura.id_cliente);
                cmd.Parameters.AddWithValue("@total", factura.total);
                cmd.Transaction = tran;
                //Obtengo el ID del elemento Insertado
                factura.id_factura = Convert.ToInt32(cmd.ExecuteScalar());
                foreach (Entidad.EntidadDetalleFactura df in factura.getDetallesFactura())
                {
                    //Agrego el ID del elemento insertado para que se pueda almacenar
                    df.id_factura = factura.id_factura.Value;
                    DAO.DAODetalleFactura.Agregar(df, cn, tran);
                    Entidad.EntidadCD cd = DAO.DAOCD.Buscar((int)df.id_cd);
                    cd.stock -= df.cantidad;
                    DAO.DAOCD.Actualizar(cd);
                }
                tran.Commit();
            }
            catch (SqlException ex)
            {
                if (cn.State == System.Data.ConnectionState.Open)
                    tran.Rollback();
                throw new ApplicationException("Error al almacenar la factura. " + ex.Message);
            }
            finally
            {
                if (cn.State == System.Data.ConnectionState.Open)
                    cn.Close();
            }      
        }
           
        public static Boolean ClienteEnUso(long clienteId)
        {
            Boolean cumple = false;
            AccesoDato ad = new AccesoDato();
            try
            {
                String sql = "Select top 1 * from factura where id_cliente = @id_cliente";
                List<SqlParameter> p = new List<SqlParameter>();
                p.Add(new SqlParameter("id_cliente", clienteId));
                SqlDataReader dr = ad.ejecutarSql(sql, p);

                while (dr.Read())
                {
                    cumple = true;
                }
            }
            catch (ApplicationException)
            {
                throw new ApplicationException("Error al obtener la factura");
            }
            finally
            {
                ad.cerrarDR();
            }

            return cumple;
        }

        public static int getUltimoId()
        {
            int id_factura = 1;
            AccesoDato ad = new AccesoDato();
            string sql = "Select MAX(id_factura) as ultimo from factura";
            try
            {
                SqlDataReader dr = ad.ejecutarSql(sql, null);
                while (dr.Read())
                {
                    id_factura = int.Parse(dr["ultimo"].ToString());
                    id_factura += 1;
                }
            }
            catch (ApplicationException)
            {
                
                throw new ApplicationException("Error al obtener el ultimo id factura");
            }
            finally
            {
                ad.cerrarDR();
            }
            return id_factura;
        }

        public static List<Entidad.VentasQueryInforme> buscarFiltro(DateTime? fechaDesde, DateTime? fechaHasta, long? numero_documento, int? id_tipo_factura, string ordenarPor = "factura.id_factura")
        {
            List<Entidad.VentasQueryInforme> lista = new List<Entidad.VentasQueryInforme>();
            List<SqlParameter> p = new List<SqlParameter>();
            AccesoDato ac = null;
            try
            {
                ac = new AccesoDato();
                string sql = @"Select factura.id_factura, tipo_factura.nombre as nombre_tipo_factura, cliente.nombre as nombre_cliente, cliente.apellido as apellido_cliente, factura.fecha as fecha_venta, factura.total
                from factura
                inner join tipo_factura on tipo_factura.id_tipo_factura = factura.id_tipo_factura
                inner join cliente on cliente.id_cliente = factura.id_cliente    
                where 1=1";

                if (fechaDesde.HasValue)
                {
                    sql += " and factura.fecha >= @fechaDesde";
                    p.Add(new SqlParameter("@fechaDesde", fechaDesde));
                }
                if (fechaHasta.HasValue)
                {
                    sql += " and factura.fecha <= @fechaHasta";
                    p.Add(new SqlParameter("@fechaHasta", fechaHasta));
                }
                if (numero_documento.HasValue)
                {
                    sql += " and cliente.numero_documento = @numero_documento";
                    p.Add(new SqlParameter("@numero_documento", numero_documento));
                }
                if (id_tipo_factura.HasValue)
                {
                    sql += " and tipo_factura.id_tipo_factura = @id_tipo_factura";
                    p.Add(new SqlParameter("@id_tipo_factura", id_tipo_factura));
                }
                sql += " group by factura.id_factura, tipo_factura.nombre, cliente.nombre, cliente.apellido, factura.fecha, factura.total";
                sql += " order by " + ordenarPor;
                SqlDataReader dr = ac.ejecutarSql(sql, p);
                while (dr.Read())
                {
                    Entidad.VentasQueryInforme ventas = new Entidad.VentasQueryInforme();
                    ventas.id_factura = int.Parse(dr["id_factura"].ToString());
                    ventas.nombre_tipo_factura = dr["nombre_tipo_factura"].ToString();
                    ventas.nombre_cliente = dr["nombre_cliente"].ToString();
                    ventas.apellido_cliente = dr["apellido_cliente"].ToString();
                    ventas.fecha_venta = DateTime.Parse(dr["fecha_venta".ToString()].ToString());
                    ventas.total = float.Parse(dr["total"].ToString());
                    lista.Add(ventas);
                }
            }
            catch (ApplicationException)
            {

                throw new ApplicationException("Error al buscar ventas");
            }
            finally
            {
                ac.cerrarDR();
            }
            return lista;
        }
    }
}
